package com.yjd.pub.order.service;

import com.alibaba.fastjson.JSON;
import com.yjd.comm.auth.model.LivingBodyAuthModel;
import com.yjd.comm.auth.service.ILivingBodyAuthService;
import com.yjd.comm.bank.model.BankModel;
import com.yjd.comm.bank.service.IBankService;
import com.yjd.comm.base.dao.IBaseDao;
import com.yjd.comm.base.enums.DbWREnums;
import com.yjd.comm.base.model.PagerModel;
import com.yjd.comm.base.service.impl.BaseServiceImpl;
import com.yjd.comm.credit.service.ICreditLineDataService;
import com.yjd.comm.enums.*;
import com.yjd.comm.funds.enums.FundsIncomeEnum;
import com.yjd.comm.funds.enums.FundsRefTableEnum;
import com.yjd.comm.funds.enums.FundsTypeEnum;
import com.yjd.comm.funds.model.FundsModel;
import com.yjd.comm.funds.service.IFundsDataService;
import com.yjd.comm.funds.service.IFundsService;
import com.yjd.comm.fundservice.dto.FundChannelInfoDto;
import com.yjd.comm.fundservice.enums.FundChannelEnum;
import com.yjd.comm.fundservice.enums.LoanApplyStatusEnum;
import com.yjd.comm.fundservice.model.FundLoanApplyModel;
import com.yjd.comm.fundservice.service.IFundLoanApplyService;
import com.yjd.comm.fundservice.util.FundChannelUtil;
import com.yjd.comm.merchant.dto.OrderStatisticDto;
import com.yjd.comm.merchant.service.IMerchantFundsService;
import com.yjd.comm.order.model.*;
import com.yjd.comm.order.service.IOrderRefuseContentService;
import com.yjd.comm.order.service.IOrderService;
import com.yjd.comm.order.service.IOrderStatusService;
import com.yjd.comm.org.model.OrganizationModel;
import com.yjd.comm.org.service.IOrganizationService;
import com.yjd.comm.project.model.ProjectInteresModel;
import com.yjd.comm.project.model.ProjectModel;
import com.yjd.comm.project.service.IProjectService;
import com.yjd.comm.repayment.model.RepaymentDataModel;
import com.yjd.comm.repayment.service.IRepaymentDataService;
import com.yjd.comm.settlement.model.ClearDayDetailModel;
import com.yjd.comm.settlement.service.IClearDayDetailService;
import com.yjd.comm.system.util.SysParamUtil;
import com.yjd.comm.user.dto.ContactInfo;
import com.yjd.comm.user.dto.ResidenceInfo;
import com.yjd.comm.user.dto.WorkInfo;
import com.yjd.comm.user.model.UserDataModel;
import com.yjd.comm.user.model.UserModel;
import com.yjd.comm.user.service.IUserDataService;
import com.yjd.comm.user.service.IUserService;
import com.yjd.comm.user.util.UserUtil;
import com.yjd.comm.util.*;
import com.yjd.comm.vo.Constant;
import com.yjd.msg.comm.annotation.MnsMsg;
import com.yjd.msg.comm.enums.MsgOrderServiceEnum;
import com.yjd.msg.comm.enums.MsgTypeEnum;
import com.yjd.msg.comm.util.MnsUtils;
import com.yjd.pub.order.dao.IOrderDao;
import com.yjd.pub.order.dao.IOrderProjectDao;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;


/**
 * <b>description</b>：订单业务实现<br>
 * <b>time</b>：2017-06-27 08:53:50 <br>
 * <b>author</b>：  yangchangyan@yijiedai.com
 */
@Service("orderService")
public class OrderServiceImpl extends BaseServiceImpl implements IOrderService {

    /**
     * 插入
     *
     * @param model
     * @return
     * @throws Exception
     */
    public OrderModel insert(OrderModel model) throws Exception {
        return this.orderDao.insertModel(model, true);
    }

    /**
     * 更新
     *
     * @param model
     * @return
     * @throws Exception
     */
    public int update(OrderModel model) throws Exception {
        return this.orderDao.updateModel(model, true);
    }


    /**
     * 更具订单id更新订单信息
     *
     * @param paramMap
     * @return
     * @throws Exception
     */
    public int updateByMap(Long order_id, Long curr_version, Map<Object, Object> paramMap) throws Exception {
        paramMap.put("order_id", order_id);
        paramMap.put("where_version", curr_version);
        return this.orderDao.updateByMap(paramMap, true);
    }

    /**
     * 根据id删除
     *
     * @param order_id
     * @return
     * @throws Exception
     */
    public int delete(long order_id) throws Exception {
        Map<Object, Object> paramMap = new HashMap<Object, Object>();
        paramMap.put("order_id", order_id);
        return this.orderDao.deleteModel(paramMap, true);
    }

    /**
     * 生成一个新的订单
     *
     * @param applyOrderModel
     * @param user_id
     * @throws Exception
     */
    @Override
    public OrderResult generateOrder(ApplyOrderModel applyOrderModel, Long user_id) throws Exception {

        //检查参数是否异常
        if (applyOrderModel == null || user_id == null) {
            FrameUtil.throwBaseException1("请求参数不能为空！");
        }

        if (applyOrderModel.getOrg_id() == null) {
            FrameUtil.throwBaseException1("请求的机构不能为空！");
        }

        if (applyOrderModel.getPj_list() == null) {
            FrameUtil.throwBaseException1("请选择项目！");
        }

        if (applyOrderModel.getLimit() == null) {
            FrameUtil.throwBaseException1("请选择分期期数！");
        }

        UserModel userModel = userService.getModelById(user_id, DbWREnums.WRITE);
        if (userModel == null) {
            FrameUtil.throwBaseException1("用户不存在");
        }

        if (userModel.getUser_status().intValue() == 1) {
            FrameUtil.throwBaseException1("您的账户已冻结，请联系客服");
        }

        //检查订单的机构是否存在
        OrganizationModel orgModel = organizationService.getModelOne(FrameUtil.newHashMap("org_id", applyOrderModel.getOrg_id(),
                "is_used", 1), DbWREnums.WRITE);
        if (orgModel == null) {
            FrameUtil.throwBaseException1("您的申请机构不存在或已暂停业务");
        }



        FundChannelInfoDto fundChannelInfoDto = FundChannelUtil.getCurrFundChannel(applyOrderModel.getOrg_id());

        if(fundChannelInfoDto==null){
            FrameUtil.throwBaseException1("系统参数配置异常");
        }

        FundChannelEnum fundChannelEnum = fundChannelInfoDto.getFundChannelEnum();
        if(fundChannelEnum==null){
            FrameUtil.throwBaseException1("系统参数错误");
        }

        //需要活体认证时需要检测活体认证结果
        if(fundChannelInfoDto.getLiving_auth()!=null&&fundChannelInfoDto.getLiving_auth().intValue()==1){
            if(applyOrderModel.getAuth_id()==null){
                FrameUtil.throwBaseException1("下单参数异常");
            }
            LivingBodyAuthModel livingBodyAuthModel = livingBodyAuthService.getModelById(applyOrderModel.getAuth_id(),DbWREnums.WRITE);
            if(livingBodyAuthModel==null||livingBodyAuthModel.getAuth_result().intValue()!=1||livingBodyAuthModel.getIs_used().intValue()==1){
                return new OrderResult(0);//需要重新活体认证
            }
            //活体认证更新
            if(livingBodyAuthService.updateByMap(FrameUtil.newHashMap("id",applyOrderModel.getAuth_id(),"is_used",1,"un_used",0))!=1){
                return new OrderResult(0);//需要重新活体认证
            }
        }

        //检查用户是否存在
        UserDataModel userDataModel = userDataService.getModelById(user_id, DbWREnums.WRITE);
        if (userDataModel == null) {
            FrameUtil.throwBaseException1("当前用户不合法");
        }
        //居住信息
        if( !UserUtil.isResidenceInfoCompleted(StringUtil.getObject(userDataModel.getResidence(), ResidenceInfo.class)) ){
            FrameUtil.throwBaseException1("请先完善您的居住信息");
        }

        //紧急联系人（List 多条）
        if( !UserUtil.isUrgentContactInfoCompleted(JSON.parseArray(userDataModel.getUrgent_contacts(), ContactInfo.class))){
            FrameUtil.throwBaseException1("请先完善您的紧急联系人信息");
        }
        //工作信息
        if( !UserUtil.isJobInfoCompleted(StringUtil.getObject(userDataModel.getJob_info(), WorkInfo.class))){
            FrameUtil.throwBaseException1("请先完善您的工作信息");
        }

        if ( !UserUtil.isUserRealNameCompleted(userDataModel)) {
            FrameUtil.throwBaseException1("请先进行实名绑定银行卡");
        }

        BankModel bankModel = bankService.getModelById(user_id, DbWREnums.READ);
        if (bankModel == null || StringUtil.isEmpty(bankModel.getBank_card_number()) || StringUtil.isEmpty(bankModel.getId_number()) || StringUtil.isEmpty(bankModel.getId_name())) {
            FrameUtil.throwBaseException1("请先绑定银行卡");
        }

        if(fundChannelInfoDto.getAuth_bank()!=null&&fundChannelInfoDto.getAuth_bank().intValue()==1){
            if(bankModel.getCertification_channel().intValue()!=fundChannelEnum.getValue()) {
                FrameUtil.throwBaseException1("请重新绑定银行卡");
            }
        }

          Integer limit = applyOrderModel.getLimit();
            //检查订单的子项目是否都是属于当前机构的
            List<OrderProjectModel> orderPrjList = new ArrayList<OrderProjectModel>();

            List<ProjectModel> prjList = projectService.getModelList(FrameUtil.newHashMap("idList", applyOrderModel.getPj_list(),
                    "org_id", applyOrderModel.getOrg_id(), "is_used", 1), DbWREnums.READ);
            Map<Long, ProjectModel> modelMap = getMapList(prjList);
            Double sum_price = 0d; //订单总金额
            Double sum_loan_price = 0d; //订单总贷款额度
            Double sum_repayment = 0d;//订单应还总额
            Double sum_payment = 0D; // 总的首付金额
            Double rate = 0D;//年化利率
            for (Long prj_id : applyOrderModel.getPj_list()) {
                ProjectModel prjModel = modelMap.get(prj_id);
                if (prjModel == null) {
                    FrameUtil.throwBaseException1("您选择的项目不存在或已下架");
                }
                if (projectService.updateByMap(FrameUtil.newHashMap("project_id", prjModel.getProject_id(), "where_used", 1, "buy_prj", 1)) != 1) {
                    FrameUtil.throwBaseException1("您选择的项目已下架");
                }
                //计算所所有项目订单总价
                Double currPrice = prjModel.getAct_price() > 0 ? prjModel.getAct_price() : prjModel.getProject_price();//目前所有价格都取活动价格为准

                OrderProjectModel orderProjectModel = new OrderProjectModel();
                orderProjectModel.setProject_id(prjModel.getProject_id());//项目id
                orderProjectModel.setLoan_price(prjModel.getLoan_price());//设置可贷额度
                orderProjectModel.setPayment(prjModel.getPayment()); // 首付金额

                //计算项目利息参数初始化
                ProjectInteresModel projectInteresModel = new ProjectInteresModel();
                projectInteresModel.setRate_config(prjModel.getRate_config());
                projectInteresModel.setLoan_price(prjModel.getLoan_price());
                projectInteresModel.setProject_id(prjModel.getProject_id());
                rate = StagesInterestUtils.getProjectRate(projectInteresModel, limit);
                orderProjectModel.setLoan_price(prjModel.getLoan_price());//设置项目可贷额度
                orderProjectModel.setLoan_rate(rate);//设置当前利率
                orderProjectModel.setReceivable_price(StagesInterestUtils.getProjectRepayment(projectInteresModel, limit));//设置项目应还总金额
                orderProjectModel.setProject_price(currPrice);//项目金额

                sum_price = ArithUtil.add(sum_price, currPrice);//统计订单总金额
                sum_loan_price = ArithUtil.add(sum_loan_price, prjModel.getLoan_price());//统计订单总的可贷额度
                sum_payment = ArithUtil.add(sum_payment, prjModel.getPayment());// 统计总的首付金额
                sum_repayment = ArithUtil.add(sum_repayment, orderProjectModel.getReceivable_price());//统计订单应收金额
                orderPrjList.add(orderProjectModel);
            }

            if (applyOrderModel.getSum_price() != null) {
                if (applyOrderModel.getSum_price().doubleValue() != sum_price.doubleValue()) {
                    FrameUtil.throwBaseException1("您申请的项目价格已调整，请重新提交订单");
                }
            }

            if (applyOrderModel.getPay_price() != null) {
                if (applyOrderModel.getPay_price().doubleValue() != sum_payment.doubleValue()) {
                    FrameUtil.throwBaseException1("您申请的项目首付价格已调整，请重新提交订单");
                }
            }

            if(fundChannelInfoDto.getLimit_price()!=null&&fundChannelInfoDto.getLimit_price().doubleValue()>0){
                if(sum_loan_price>fundChannelInfoDto.getLimit_price().doubleValue()){
                    FrameUtil.throwBaseException1("您申请的贷款额度超出限额");
                }
            }
            //暂时不做信用额度判断
           /* if(OrgMoldEnum.ORDINARY.getCode()==orgModel.getOrg_mold().intValue()){
                //检查用户信用额度是否够使用
                if (userDataModel.getResidual_amount() < sum_loan_price) {
                    FrameUtil.throwBaseException1("您的信用额度不够");
                }

                if (sum_loan_price > sum_price) {
                    FrameUtil.throwBaseException1("您的贷款额度不能大于项目总额");
                }

                //检查当前使用额度是否大于订单总金额
                if (sum_loan_price <= 0) {
                    FrameUtil.throwBaseException1("您的贷款额度不合法");
                }
            }*/

            //每期还款的金额
            Double limit_price = ArithUtil.round(ArithUtil.div(sum_repayment, limit));
            //应收利息
            Double interest_price = ArithUtil.sub(sum_repayment, sum_loan_price);//总利息
            Long currTime = FrameUtil.getTime(null);
            OrderModel orderModel = new OrderModel();
            orderModel.setOrg_id(applyOrderModel.getOrg_id());//机构id
            orderModel.setUser_id(user_id);//用户id
            orderModel.setOrder_amount(sum_price);//订单总金额
            orderModel.setLoan_amount(sum_loan_price);//贷款金额
            orderModel.setPayment(sum_payment); // 总的首付金额
            orderModel.setCash_amount(ArithUtil.sub(sum_price, sum_loan_price));//现金支付金额
            orderModel.setPeriod(limit);//期数
            orderModel.setLoan_rate(rate);//利率
            orderModel.setInterest_price(interest_price);//总利息
            orderModel.setInterest_pay(0d);
            orderModel.setTotal_amount(sum_repayment);//应还总金额
            orderModel.setStatus(sum_payment > 0 ? StagesStatusEnum.APPLY_SUCCESS.getCode() : StagesStatusEnum.MERCHANT_HANDING.getCode());//首付为零则直接处理中
            orderModel.setCreate_time(currTime);
            orderModel.setLast_update_time(currTime);
            orderModel.setOrder_no(OrderNoFactoryUtils.getOrderNo());
            orderModel.setOrder_type(fundChannelEnum.getValue()>1?3:2);//设置订单类型 1普通订单  2 vip订单
            orderModel.setFund_channel(fundChannelEnum.getValue()); // 资金渠道
            orderModel.setLiving_identify_id(applyOrderModel.getAuth_id()==null?0:applyOrderModel.getAuth_id());//活体认证关联id
            orderModel = orderDao.insertModel(orderModel, true);

            //处理订单子订单
            for (OrderProjectModel orderProjectModel : orderPrjList) {
                orderProjectModel.setOrder_id(orderModel.getOrder_id());
                orderProjectModel.setCreate_time(currTime);
                orderProjectModel.setDiscount_amount(0d);
                orderProjectModel.setLast_update_time(currTime);
            }
            //批量插入子订单
            orderProjectDao.insertBatch(orderPrjList, true);

            //根据选择获取还款方式，生成对应的还款表报 (待商户确认后生成还款报表)
            //repayment(applyOrderModel.getLimit(), limit_price, currTime, orderModel.getOrder_id());

            //记录订单当前状态
            orderStatusService.insert(new OrderStatusModel(orderModel.getOrder_id(), StagesStatusEnum.APPLY_SUCCESS, StagesEventEnum.APPLY.getLabel(), currTime));

           /* if (OrgMoldEnum.ORDINARY.getCode() == orgModel.getOrg_mold().intValue()) {
                //更新用户信用额度
                if (userDataService.updateByMap(FrameUtil.newHashMap("use_credit", sum_loan_price, "user_id", user_id, "where_version",
                        userDataModel.getVersion())) != 1) {
                    FrameUtil.throwBaseException1("系统繁忙，请重试提交！");
                }

                //记录用户信用额度使用明细
                CreditLineDataModel creditLineDataModel = new CreditLineDataModel();
                creditLineDataModel.setUser_id(user_id);
                creditLineDataModel.setCost(sum_loan_price);
                creditLineDataModel.setType(RecordIncr.reduceAm.getCode());
                creditLineDataModel.setResidual_amount(ArithUtil.sub(userDataModel.getResidual_amount(), sum_loan_price));
                creditLineDataModel.setRef_id(orderModel.getOrg_id());
                creditLineDataModel.setRef_type(CreditDataRefTableEnum.mfq_order.getValue());
                creditLineDataModel.setCreate_time(currTime);
                creditLineDataService.insert(creditLineDataModel);
            }*/

            // 提醒商户处理
            if (StagesStatusEnum.parse(orderModel.getStatus()) == StagesStatusEnum.MERCHANT_HANDING) {
                MerchantPushUtil.pushMessage(orderModel.getOrg_id(), Constant.SysParamKeyEnum.PUSH_TPL_ORDER_PROCESS_REMINDER);
            }
            return new OrderResult(orderModel.getOrder_id(), sum_loan_price, limit, limit_price, orderModel.getOrder_no(),1);

    }

    /**
     * 生成用户还款报表
     *
     * @param limit
     * @param price
     * @param currtime
     * @param valueDate 起息日
     * @throws Exception
     */
    private void repayment(Integer limit, Double price, Long currtime, Long order_id,Long user_id,Long org_id,Long valueDate,Integer repayment_type) throws Exception {
        if (limit == null || price == null || limit == 0 || price == 0 || order_id == null) {
            FrameUtil.throwBaseException1("生成还款报表异常");
        }

        List<RepaymentDataModel> repayMentList = new ArrayList<RepaymentDataModel>();
        for (int i = 1; i <= limit; i++) {
            RepaymentDataModel dataModel = new RepaymentDataModel();
            dataModel.setOrder_id(order_id);//主订单id
            dataModel.setPeriod(i);//还款期数
            dataModel.setEstimation_repayment_time(DateUtil.getLastSecond(DateUtil.addMonth(valueDate, i)));//还款日期
            dataModel.setOverdue_price(0d);//罚息默认为0
            dataModel.setCapital(0d);//应还本金
            dataModel.setInterest(0d);//等额本息默认为0
            dataModel.setDiscount_amount(0d);//减免金额
            dataModel.setRepayment(0d);//实还金额
            dataModel.setRepayment_amount(price);//还款金额
            dataModel.setRepayment_status(0);//还款状态
            dataModel.setCreate_time(currtime);//生成时间
            dataModel.setLast_update_time(currtime);//修改时间
            dataModel.setUser_id(user_id);//用户id
            dataModel.setOrg_id(org_id);//机构id
            dataModel.setVersion(0L);
            dataModel.setRepayment_type(repayment_type);
            repayMentList.add(dataModel);
        }
        repaymentDataService.insertBatch(repayMentList);
    }


    private Map<Long, ProjectModel> getMapList(List<ProjectModel> prjList) throws Exception {
        Map<Long, ProjectModel> mapList = new HashMap<Long, ProjectModel>();
        for (ProjectModel model : prjList) {
            mapList.put(model.getProject_id(), model);
        }
        return mapList;
    }

    /**
     * 搜索项目
     *
     * @param param
     * @return
     * @throws Exception
     */
    @Override
    public PagerModel getOrderInfoList(Map<String, Object> param) throws Exception {
        return this.getPageModel(param, "getOrderInfoList", DbWREnums.READ);
    }


    /**
     * 自助取消订单，包括两种情况：
     * 1、商户未确认订单前取消
     * 2、商户确认订单后，在第一期还款支付之前，用户申请取消，此步骤需要商户同意才能取消
     *
     * @param user_id
     * @param order_id
     * @throws Exception
     */
    @Override
    public void myselfCanel(Long user_id, Long order_id) throws Exception {
        if (user_id == null || order_id == null) {
            FrameUtil.throwBaseException1("请求参数不能为空");
        }

        UserModel userModel = userService.getModelById(user_id, DbWREnums.WRITE);
        if (userModel == null) {
            FrameUtil.throwBaseException1("用户不存在");
        }

        OrderModel orderModel = orderDao.getModelById(order_id, true);
        if (orderModel == null) {
            FrameUtil.throwBaseException1("订单不存在");
        }

        /**
         * 接入资金渠道后，用户支付首付后，不可再取消订单
         */
        if(orderModel.getFund_channel() > 1 && StagesStatusEnum.MERCHANT_HANDING.getCode() == orderModel.getStatus().intValue()){
            FrameUtil.throwBaseException1("您的订单不可取消");
        }

        if (orderModel.getUser_id().intValue() != user_id.intValue()) {
            FrameUtil.throwBaseException1("您操作的订单不属于您自己的");
        }

        Long currtime = FrameUtil.getTime(null);
        if (    StagesStatusEnum.APPLY_SUCCESS.getCode() != orderModel.getStatus().intValue() &&
                StagesStatusEnum.MERCHANT_HANDING.getCode() != orderModel.getStatus().intValue() &&
                StagesStatusEnum.REPAYMENTING.getCode() != orderModel.getStatus().intValue() ) {
            FrameUtil.throwBaseException1("您的订单不可取消");
        }

        /**
         * 以下处理取消订单的状态变化：
         * 1、商户未确认订单前取消，订单变成：已取消
         * 2、商户确认订单后，在第一期还款支付之前，用户申请取消，订单变成：取消受理中（然后由商户去审批是否同意取消，并退款）
         */
        StagesStatusEnum statusEnum = null;
        StagesEventEnum eventEnum = null;
        Map orderParam = null;

        if (StagesStatusEnum.APPLY_SUCCESS.getCode() == orderModel.getStatus().intValue() ||
                StagesStatusEnum.MERCHANT_HANDING.getCode() == orderModel.getStatus().intValue() ) {
            orderParam = FrameUtil.newHashMap("order_id", order_id, "where_version", orderModel.getVersion(), "status",
                    StagesStatusEnum.MYSEFL_CANCEL.getCode(), "last_update_time", currtime); //设置自助更新订单参数
            statusEnum = StagesStatusEnum.MYSEFL_CANCEL;
            eventEnum = StagesEventEnum.CANCEL;

            //暂时不考虑信用额度
           /* //如果为普通订单则需要将信用记录退回
            if(OrgMoldEnum.ORDINARY.getCode()==orderModel.getOrder_type()){
                //用户自己取消后退回用户信用额度
                UserDataModel userDataModel = userDataService.getModelOne(FrameUtil.newHashMap("user_id", user_id), DbWREnums.WRITE);
                if (userDataModel == null) {
                    FrameUtil.throwBaseException1("用户信息错误！");
                }
                userDataService.recoveryCredit(userDataModel, order_id, orderModel.getLoan_amount(), CreditDataRefTableEnum.mfq_order, currtime);
            }*/

            if(StagesStatusEnum.MERCHANT_HANDING.getCode() == orderModel.getStatus().intValue()){
                // 将首付款退回到用户账户中
                fundsService.paymentRefund(orderModel.getUser_id(), orderModel.getPayment(), orderModel.getOrder_id());
            }
        }

        if (StagesStatusEnum.REPAYMENTING.getCode() == orderModel.getStatus().intValue()) {
            if (orderModel.getLimit_pay().intValue() == 0) {
                repaymentDataService.updatePlanByOrder(orderModel, 1);
                RepaymentDataModel repaymentDataModel = repaymentDataService.getModelOne(FrameUtil.newHashMap("order_id", order_id, "period", 1), DbWREnums.WRITE);
                if (repaymentDataModel == null) {
                    FrameUtil.throwBaseException1("您的订单异常！");
                }

                if (repaymentDataModel.getEstimation_repayment_time() > currtime) {
                    orderParam = FrameUtil.newHashMap(
                            "order_id", order_id,
                            "where_version", orderModel.getVersion(),
                            "status", StagesStatusEnum.MERCHANT_CONFIRM_CANCEL.getCode(),
                            "approve_refund_time", currtime, // 申请取消的时间，商户拒绝或通过后会更新此时间
                            "last_update_time", currtime);//设置确认取消申请的参数
                    statusEnum = StagesStatusEnum.MERCHANT_CONFIRM_CANCEL;
                    eventEnum = StagesEventEnum.CONFIRM_AFTER_CANCEL;

                } else {
                    FrameUtil.throwBaseException1("您的订单还款已超过一期，不可取消");
                }
            } else {
                FrameUtil.throwBaseException1("您的订单已经还过一期，不可取消");
            }
        }
        //更新订单状态
        if (orderDao.updateByMap(orderParam, true) != 1) {
            FrameUtil.throwBaseException1("订单表取消失败");
        }

        //记录订单当前状态
        orderStatusService.insert(new OrderStatusModel(orderModel.getOrder_id(), statusEnum, eventEnum.getLabel(), currtime));
        // 推送提醒商户去处理
        if (StagesStatusEnum.REPAYMENTING.getCode() == orderModel.getStatus().intValue()) {
            MerchantPushUtil.pushMessage(orderModel.getOrg_id(), Constant.SysParamKeyEnum.PUSH_TPL_CHARGEBACK_PROCESS_REMINDER);
        }
    }


    /**
     * 商户确认订单
     *
     * @param org_id
     * @param order_id
     * @throws Exception
     */
    @MnsMsg
    @Override
    public void merchantConfirm(Long org_id, Long order_id) throws Exception {
        if (org_id == null || order_id == null) {
            FrameUtil.throwBaseException1("参数不能为空！");
        }
        OrderModel orderModel = orderDao.getModelById(order_id, true);
        if (orderModel == null) {
            FrameUtil.throwBaseException1("订单不存在");
        }

        OrganizationModel organizationModel = organizationService.getModelById(org_id, DbWREnums.READ);
        if (organizationModel == null) {
            FrameUtil.throwBaseException1("当前机构不存在");
        }

        if (orderModel.getOrg_id().intValue() != organizationModel.getOrg_id().intValue()) {
            FrameUtil.throwBaseException1("当前订单不属于您的机构");
        }

        if (StagesStatusEnum.MERCHANT_HANDING.getCode() != orderModel.getStatus()) {
            FrameUtil.throwBaseException1("当前订单状态不可修改");
        }

        /**
         * 如果orderModel.getFund_channel() > 1，说明使用的第三方资金，分两个异步过程：
         * 1、先调用第三方贷款申请
         * 2、等待异步回调，根据是否通过做相应处理：
         *  通过：生成还款报表、更新商户资金
         *  未通过：拒绝订单
         */
        Long currTime = FrameUtil.getTime(null);
        if(orderModel.getFund_channel().intValue() > FundChannelEnum.YMFQ.getValue()){

            // 提交借款申请
          //  this.fundLoanApplyService.loanApply(orderModel.getOrder_id());

            //更新订单状态为贷款申请中
            if (orderDao.updateByMap(FrameUtil.newHashMap("order_id", order_id, "where_version", orderModel.getVersion(), "status",
                    StagesStatusEnum.LOAN_APPLY.getCode(), "last_update_time", currTime, "confirm_time", currTime), true) != 1) {
                FrameUtil.throwBaseException1("订单表拒绝失败");
            }

            //记录订单当前状态
            orderStatusService.insert(new OrderStatusModel(orderModel.getOrder_id(), StagesStatusEnum.LOAN_APPLY, StagesEventEnum.LOAN_APPLY.getLabel(), currTime));

            // 发送贷款请求消息
            MnsUtils.createMessage(orderModel.getOrder_id().toString(), MsgTypeEnum.LOAN_APPLY_MSG, MsgOrderServiceEnum.PUBLIC_ORDER_SERVICE,
                    FrameUtil.newHashMap("order_id", orderModel.getOrder_id()));
        } else {

            //获取当前时间的00:00:00 计息时间为商户确认的结算日
            Long currDate = DateUtil.getTimeDayByTimestamp(currTime);
            //更新订单状态
            if (orderDao.updateByMap(FrameUtil.newHashMap("order_id", order_id, "where_version", orderModel.getVersion(), "status",
                    StagesStatusEnum.REPAYMENTING.getCode(), "last_update_time", currTime, "confirm_time", currTime, "clear_date", currDate), true) != 1) {
                FrameUtil.throwBaseException1("订单表拒绝失败");
            }

            Long valueDate = DateUtil.addDay(currDate, 1); //起息日
            Double period_price = ArithUtil.round(ArithUtil.div(orderModel.getTotal_amount(), orderModel.getPeriod()));
            //更新用户资金表信息 累计借款金额+  累计成交金额+  待回收金额+
            if(fundsService.updatByMap(orderModel.getUser_id(),FrameUtil.newHashMap("add_borrow",orderModel.getLoan_amount(),"add_price",
                    orderModel.getOrder_amount(),"add_recovery",orderModel.getTotal_amount()))!=1){
                FrameUtil.throwBaseException1("更新用户资金成交信息失败");
            }

            //生成还款报表
            repayment(orderModel.getPeriod(), period_price, currTime, orderModel.getOrder_id(),orderModel.getUser_id(),orderModel.getOrg_id(),valueDate,orderModel.getOrder_type());

            //记录订单当前状态
            orderStatusService.insert(new OrderStatusModel(orderModel.getOrder_id(), StagesStatusEnum.REPAYMENTING, StagesEventEnum.MERCHANT_CONFIRM.getLabel(), currTime));

            //商户资金表更新 更新普通订单累计金额/待收回收累计金额 vip订单累计金额 vip订单累计首付
            Map updateMFundsParam  = FrameUtil.newHashMap();
            updateMFundsParam.put("update_time",currDate);
            if(OrgMoldEnum.ORDINARY.getCode()==orderModel.getOrder_type()){
                updateMFundsParam.put("add_price",orderModel.getOrder_amount());
            }else if(OrgMoldEnum.VIP.getCode()==orderModel.getOrder_type()){
                updateMFundsParam.put("add_recovery_price",orderModel.getTotal_amount());//待回收金额
                updateMFundsParam.put("add_vip_price",orderModel.getOrder_amount());//订单金额
                updateMFundsParam.put("add_vip_frist_price",orderModel.getPayment());//vip订单累计首付金额
            }
            if(merchantFundsService.updataByMap(orderModel.getOrg_id(),updateMFundsParam)!=1){
                FrameUtil.throwBaseException1("更新商户资金信息失败");
            }

            //医美做为资金方通过后想资金贷款表中新增一条记录
            FundLoanApplyModel loanApplyModel =  new FundLoanApplyModel();
            loanApplyModel.setFund_channel(FundChannelEnum.YMFQ.getValue());
            loanApplyModel.setBus_type(1);
            loanApplyModel.setOrder_id(orderModel.getOrder_id());
            loanApplyModel.setUser_id(orderModel.getUser_id());
            loanApplyModel.setPrice(orderModel.getOrder_amount());
            loanApplyModel.setLoan_price(orderModel.getLoan_amount());
            loanApplyModel.setLoan_rate(orderModel.getLoan_rate());
            loanApplyModel.setPeriods(orderModel.getPeriod());
            loanApplyModel.setRepayment_type(1);//1等额本息 2 每月还息，到期还本
            loanApplyModel.setOrg_id(orderModel.getOrg_id());
            loanApplyModel.setStatus(LoanApplyStatusEnum.REPAYMENTS.getCode());
            loanApplyModel.setCreate_time(currTime);
            loanApplyModel.setUpdate_time(currTime);
            fundLoanApplyService.insert(loanApplyModel);

            // 商户确认订单成功消息
            JpushUtil.pushMessage(
                    orderModel.getUser_id(),
                    Constant.SysParamKeyEnum.PUSH_TPL_MERCHANT_CONFIRM,
                    orderModel.getOrder_no(),
                    orderModel.getLoan_amount(),
                    orderModel.getPeriod());
        }

    }

    /**
     * 商户拒绝订单
     *
     * @param org_id
     * @param order_id
     * @throws Exception
     */
    @Override
    public void merchantRefuse(Long org_id, Long order_id, OrderRefuseEnum orderRefuseEnum, String content) throws Exception {
        if (org_id == null || order_id == null) {
            FrameUtil.throwBaseException1("参数不能为空！");
        }

        OrderModel orderModel = orderDao.getModelById(order_id, true);
        if (orderModel == null) {
            FrameUtil.throwBaseException1("订单不存在");
        }

        OrganizationModel organizationModel = organizationService.getModelById(org_id, DbWREnums.READ);
        if (organizationModel == null) {
            FrameUtil.throwBaseException1("当前机构不存在");
        }

        if (orderModel.getOrg_id().intValue() != organizationModel.getOrg_id().intValue()) {
            FrameUtil.throwBaseException1("当前订单不属于您的机构");
        }

        if (StagesStatusEnum.MERCHANT_HANDING.getCode() != orderModel.getStatus()) {
            FrameUtil.throwBaseException1("当前订单状态不能拒绝");
        }

        if (orderRefuseEnum == null) {
            FrameUtil.throwBaseException1("请选择拒绝原因");
        }

        Long currTime = FrameUtil.getTime(null);
        if (OrderRefuseEnum.C.getCode().equals(orderRefuseEnum.getCode())) {
            if (StringUtil.isEmpty(content)) {
                FrameUtil.throwBaseException1("请填写拒绝原因");
            }

            if (content.length() > 200) {
                FrameUtil.throwBaseException1("拒绝原因不能大于200字");
            }
            insetRefuseContent(order_id, content, currTime);
        }
        //更新订单状态
        if (orderDao.updateByMap(FrameUtil.newHashMap("order_id", order_id, "where_version", orderModel.getVersion(), "status",
                StagesStatusEnum.MERCHANT_REFUSAL.getCode(), "last_update_time", currTime, "confirm_time", currTime, "refuse_code", orderRefuseEnum.getCode()), true) != 1) {
            FrameUtil.throwBaseException1("订单表拒绝失败");
        }

        //暂时不考虑信用额度
      /*  //普通订单需要将用户信用额度退回
        if(OrgMoldEnum.ORDINARY.getCode()==orderModel.getOrder_type()){
            //取消后退回用户信用额度
            UserDataModel userDataModel = userDataService.getModelOne(FrameUtil.newHashMap("user_id", orderModel.getUser_id()), DbWREnums.WRITE);
            if (userDataModel == null) {
                FrameUtil.throwBaseException1("用户信息错误！");
            }
            userDataService.recoveryCredit(userDataModel, order_id, orderModel.getLoan_amount(), CreditDataRefTableEnum.mfq_order, currTime);
        }*/

        //记录订单当前状态
        orderStatusService.insert(new OrderStatusModel(orderModel.getOrder_id(), StagesStatusEnum.MERCHANT_REFUSAL, StagesEventEnum.MERCHANT_REFUSE.getLabel(), currTime));

        // 将首付款退回到用户账户中
        if (orderModel.getPayment() > 0 && StagesStatusEnum.MERCHANT_HANDING.getCode()==orderModel.getStatus().intValue()) {
            fundsService.paymentRefund(orderModel.getUser_id(), orderModel.getPayment(), orderModel.getOrder_id());
        }

        // 商户取消订单成功消息
        JpushUtil.pushMessage(
                orderModel.getUser_id(),
                Constant.SysParamKeyEnum.PUSH_TPL_MERCHANT_CANCEL,
                orderModel.getOrder_no());
    }

    private void insetRefuseContent(Long order_id, String content, Long currtime) throws Exception {
        OrderRefuseContentModel model = new OrderRefuseContentModel();
        model.setContent(content);
        model.setOrder_id(order_id);
        model.setCreate_time(currtime);
        orderRefuseContentService.insert(model);
    }

    @Override
    public void settlement(Long previousTime) throws Exception {
        this.settlement(previousTime, previousTime);
    }

    @Override
    public void settlement(Long start, Long end) throws Exception {
        Long current = FrameUtil.getTime();
        if (null == start) {
            start = current;
        }
        if (null == end) {
            end = current;
        }

        // 计算start对应的00:00:00 000时刻的秒数
        start = DateUtil.getFristSecond(start);

        // end对应的23:59:59 999时刻的秒数
        end = DateUtil.getLastSecond(end);

        // 循环生成结算单
        for( ; start <= end ; ){

            Long clear_date_start = start; // 00:00:00 000时刻
            Long clear_date_end = DateUtil.getLastSecond(start); // 23:59:59 999时刻

            // 下一天
            start = DateUtil.addDay(start, 1);

            /**
             * 订单类型  1 普通订单  2 vip订单
             * 普通订单：结算金额=首付金额+贷款金额=订单总额
             * vip订单：结算金额=首付金额
             *
             * 两种订单会进行结算
             * 1、clear_date在结算区间[start, end]上，状态为[还款中,商户已取消]的订单
             * 2、approve_refund_time申请退单时间在结算区间[start, end]上，并且商户通过了退单请求
             */
            Map<String, Object> filter = FrameUtil.newHashMap(
                    "clear_date_gte", clear_date_start, "clear_date_lte", clear_date_end,
                    "approve_refund_time_gte", clear_date_start, "approve_refund_time_lte", clear_date_end, "refund_status", 1);
            int skip = 0;
            int size = 20;
            while (true) {
                List<OrderModel> settlementOrders = this.querySettlementOrder(filter, skip, size, DbWREnums.WRITE);

                // 分批查询结算订单（每次20条），避免单次处理数据过大
                if (null == settlementOrders || settlementOrders.size() == 0) {
                    break;
                }

                this.generateClearDayDetail(settlementOrders, current, clear_date_start, clear_date_end);

                // 忽略前面N条
                skip = skip + size;
            }
        }

    }

    private void generateClearDayDetail(List<OrderModel> settlementOrders, Long current, Long clear_date_start, Long clear_date_end) throws Exception {
        List<ClearDayDetailModel> dayDetails = new ArrayList<ClearDayDetailModel>();
        ClearDayDetailModel dayDetail = null;
        for (OrderModel order : settlementOrders) {
            dayDetail = new ClearDayDetailModel();
            dayDetail.setOrder_id(order.getOrder_id());
            dayDetail.setFund_channel(order.getFund_channel());
            dayDetail.setUser_id(order.getUser_id());
            dayDetail.setType(1);
            dayDetail.setFlag(-1);
            dayDetail.setClear_date(Integer.valueOf(DateUtil.format(new Date(order.getClear_date() * 1000), DateUtil.PATTERN_yyyyMMdd)));
            dayDetail.setStatus(StagesStatusEnum.REPAYMENTING.getCode());

            if (StagesStatusEnum.MERCHANT_CANCEL.getCode() == order.getStatus()) {
                // 如果订单是当天确认通过，然后再取消的，不进行结算
                String refund_date = DateUtil.timestampToDateString(order.getApprove_refund_time(), DateUtil.PATTERN_yyyy_MM_dd);
                if(refund_date.equals(DateUtil.timestampToDateString(order.getClear_date(), DateUtil.PATTERN_yyyy_MM_dd))){
                    continue;
                }
                String clearDate = DateUtil.timestampToDateString(clear_date_start, DateUtil.PATTERN_yyyy_MM_dd);
                if(clearDate.equals(refund_date)){
                    dayDetail.setStatus(StagesStatusEnum.MERCHANT_CANCEL.getCode());
                    dayDetail.setType(2);
                    dayDetail.setFlag(1);
                    dayDetail.setClear_date(Integer.valueOf(DateUtil.format(new Date(order.getApprove_refund_time() * 1000), DateUtil.PATTERN_yyyyMMdd)));
                }
            }
            dayDetail.setPayment(ArithUtil.sub(order.getOrder_amount(), order.getLoan_amount()));
            dayDetail.setLoan_amount(order.getLoan_amount());
            //资金渠道当天只结算首付金额
            dayDetail.setClear_price(order.getPayment());
            dayDetail.setOrder_price(order.getOrder_amount());
            dayDetail.setOrg_id(order.getOrg_id());
            dayDetail.setCreate_time(current);
            dayDetails.add(dayDetail);
        }
        clearDayDetailService.insertBatch(dayDetails);
    }

    @Override
    public List<RefundOrderModel> queryRefundOrder(Map<String, Object> paramMap, DbWREnums write) throws Exception {
        List<RefundOrderModel> models = new ArrayList<RefundOrderModel>();
        PagerModel orders = this.getPageModel(paramMap, "queryRefundOrder", this.getBaseDao(), write);
        for (Object obj : orders.getDataList()) {
            models.add((RefundOrderModel) obj);
        }
        return models;
    }

    @Override
    public List<OrderModel> querySettlementOrder(Map<String, Object> paramMap, long skip, int size, DbWREnums write) throws Exception {
        if (paramMap == null) {
            paramMap = FrameUtil.newHashMap();
        }
        paramMap.put("dbtype", this.getBaseDao().getDbtype());
        paramMap.put("rowstartindex", skip);
        paramMap.put("rowendindex", size);

        return this.orderDao.querySettlementOrder(paramMap, write.isWrite());
    }

    @Override
    public int refundProcess(Long org_id, Long order_id, RefundOrderStatus type, OrderRefuseEnum orderRefuseEnum, String content) throws Exception {

        OrderModel order = orderDao.getModelById(order_id, true);
        if (StagesStatusEnum.MERCHANT_CONFIRM_CANCEL.getCode() != order.getStatus()) {
            FrameUtil.throwBaseException1("当前订单状态不可修改");
        }

        Long currentTime = FrameUtil.getTime();
        Map updateData = FrameUtil.newHashMap(
                "order_id", order_id,
                "where_version", order.getVersion(),
                "refund_status", type.getCode(),
                "approve_refund_time", currentTime,
                "last_update_time", currentTime);

        int count = 0;
        Double manage_price = 0.0D;
        StagesStatusEnum stagesStatusEnum = null;
        StagesEventEnum stagesEventEnum = null;
        // 如果通过（商户同意退款），需要更新订单状态为已取消，拒绝则订单状态为还款中
        if (type == RefundOrderStatus.REFUND_PASS && order.getFund_channel().intValue() == FundChannelEnum.YMFQ.getValue()) {
            repaymentDataService.updatePlanByOrder(order, 1);
            RepaymentDataModel rdm = repaymentDataService.getModelOne(FrameUtil.newHashMap("order_id", order_id, "period", 1), DbWREnums.WRITE);
            // 此时退单需收取利息(即服务费)
            manage_price = repaymentDataService.calcManagePrice(rdm.getOrder_id(), rdm.getPeriod());

            // 商户同意退款，将还款报表更新为取消
            count = repaymentDataService.updateByMap(FrameUtil.newHashMap(
                    "where_order_id", order_id,
                    "where_version", 0,
                    "repayment_status", 2,
                    "last_update_time", currentTime));
            if (count != order.getPeriod()) {
                FrameUtil.throwBaseException1("订单表报更新失败");
            }

            // 更新第一期罚息金额（记为管理费的金额）
            count = repaymentDataService.updateByMap(FrameUtil.newHashMap(
                    "where_order_id", order_id, "where_period", 1,
                    "overdue_price", ArithUtil.add(manage_price, rdm.getOverdue_price()) ));
            if (count != 1) {
                FrameUtil.throwBaseException1("订单表报更新失败");
            }

            updateData.put("manage_price", ArithUtil.add(manage_price, order.getManage_price()));
            updateData.put("status", StagesStatusEnum.MERCHANT_CANCEL.getCode());
            stagesStatusEnum = StagesStatusEnum.MERCHANT_CANCEL;
            stagesEventEnum = StagesEventEnum.CONFIRM_CONFIRM_CANCEL;

            //商户资金表更新 更新普通订单累计金额/待收回收累计金额 vip订单累计金额 vip订单累计首付
            Map updateMFundsParam  = FrameUtil.newHashMap();
            updateMFundsParam.put("update_time",currentTime);

            if(OrgMoldEnum.ORDINARY.getCode()==order.getOrder_type()) {
                //普通订单 取消后退回用户信用额度 更新账户普通订单成交额
                UserDataModel userDataModel = userDataService.getModelOne(FrameUtil.newHashMap("user_id", order.getUser_id()), DbWREnums.WRITE);
                if (userDataModel == null) {
                    FrameUtil.throwBaseException1("用户信息错误！");
                }
                userDataService.recoveryCredit(userDataModel, order_id, order.getLoan_amount(), CreditDataRefTableEnum.mfq_order, currentTime);
                updateMFundsParam.put("add_back_price",order.getOrder_amount());//普通订单退单金额

            } else if(OrgMoldEnum.VIP.getCode()==order.getOrder_type()){
                updateMFundsParam.put("add_vip_back_price",order.getOrder_amount());//vip订单退单金额
                updateMFundsParam.put("reduce_vip_frist_price",order.getPayment());//vip订单累计首付金额
                updateMFundsParam.put("reduce_recovery_price",order.getTotal_amount());//待回收金额
            }
            if(merchantFundsService.updataByMap(order.getOrg_id(),updateMFundsParam)!=1){
                FrameUtil.throwBaseException1("更新商户资金信息失败");
            }

            FundsModel fundsModel = this.fundsService.getModelById(order.getUser_id(), DbWREnums.WRITE);
            if(fundsModel==null){
                FrameUtil.throwBaseException1("用户资金账户不存在");
            }

            count = fundsService.addPriceOfOrderRturn(FrameUtil.newHashMap(
                    "user_id", fundsModel.getUser_id(),
                    "where_version", fundsModel.getVersion(),
                    "reduce_borrow", order.getLoan_amount(),
                    "reduce_price", order.getOrder_amount(),
                    "reduce_recovery", order.getTotal_amount(),
                    "manage_price", manage_price,
                    "change_price", ArithUtil.sub(order.getPayment(), manage_price) // 退单时利息从首付款中扣除
            ));

            if (count != 1) {
                FrameUtil.throwBaseException1("更新用户资金失败");
            }

            Double balance = ArithUtil.add(fundsModel.getAvailable(), order.getPayment());
            // 记录退款流水
            fundsDataService.insertFundsData(fundsModel.getUser_id(),order.getPayment(), balance,
                    FundsIncomeEnum.ADD, FundsTypeEnum.REFUND,rdm.getOrder_id().toString(), FundsRefTableEnum.MFQ_ORDER, currentTime);
            // 记录罚息流水
            fundsDataService.insertFundsData(fundsModel.getUser_id(),manage_price, ArithUtil.sub(balance, manage_price),
                    FundsIncomeEnum.REDUCE, FundsTypeEnum.MANAGE,rdm.getOrder_id().toString(), FundsRefTableEnum.MFQ_ORDER, currentTime);
        } else {
            if (orderRefuseEnum == null) {
                FrameUtil.throwBaseException1("请选择拒绝原因");
            }

            updateData.put("status", StagesStatusEnum.REPAYMENTING.getCode());
            updateData.put("refuse_code", orderRefuseEnum.getCode());

            if (OrderRefuseEnum.C.getCode().equals(orderRefuseEnum.getCode())) {
                if (StringUtil.isEmpty(content)) {
                    FrameUtil.throwBaseException1("请填写拒绝原因");
                }

                if (content.length() > 200) {
                    FrameUtil.throwBaseException1("拒绝原因不能大于200字");
                }
                //记录拒绝原因
                insetRefuseContent(order_id, content, currentTime);
            }
            stagesStatusEnum = StagesStatusEnum.REPAYMENTING;
            stagesEventEnum = StagesEventEnum.MERCHANT_REFUSE_CANCEL;
        }

        //更新订单状态
        count = orderDao.updateByMap(updateData, true);
        if (count != 1) {
            FrameUtil.throwBaseException1("更新订单失败，请稍后重试。");
        }
        //记录订单当前状态
        orderStatusService.insert(new OrderStatusModel(order.getOrder_id(), stagesStatusEnum, stagesEventEnum.getLabel(), currentTime));

        // 推送处理消息
        if (type == RefundOrderStatus.REFUND_PASS) {
            JpushUtil.pushMessage(
                    order.getUser_id(),
                    Constant.SysParamKeyEnum.PUSH_TPL_REFUND_PASS,
                    order.getOrder_no(),
                    NumberUtil.formatNumber(manage_price, NumberUtil.FORMAT_4));
        } else {
            JpushUtil.pushMessage(
                    order.getUser_id(),
                    Constant.SysParamKeyEnum.PUSH_TPL_REFUND_REFUSE,
                    order.getOrder_no());
        }

        return count;
    }


    /**
     * 首付款成功到账处理
     *
     * @param order_id
     * @throws Exception
     */
    @Override
    public void firstPaymentSuccess(Long order_id) throws Exception {
        if(order_id==null){
            FrameUtil.throwBaseException1("订单号不能为空");
        }
        OrderModel orderModel = this.orderDao.getModelById(order_id,true);
        if(StagesStatusEnum.APPLY_SUCCESS.getCode()==orderModel.getStatus().intValue()){
            Long currtime = FrameUtil.getTime(null);
            //首付扣款
            fundsService.firstPay(orderModel.getUser_id(),orderModel.getPayment(),orderModel.getOrder_id().toString(),currtime);
            //更新订单状态
            if (orderDao.updateByMap(FrameUtil.newHashMap("order_id", order_id, "where_version", orderModel.getVersion(), "status",
                    StagesStatusEnum.MERCHANT_HANDING.getCode(), "last_update_time", currtime), true) != 1) {
                FrameUtil.throwBaseException1("订单表拒绝失败");
            }

            // 首付款成功到账，提醒商户去处理
            MerchantPushUtil.pushMessage(orderModel.getOrg_id(), Constant.SysParamKeyEnum.PUSH_TPL_ORDER_PROCESS_REMINDER);
        }else{
            FrameUtil.throwBaseException1("当前订单状态不是待处理状态");
        }
    }

    @Override
    public List<OrderModel> queryRepaymentOrder(Map<String, Object> paramMap, DbWREnums write) throws Exception {

        PagerModel pagerModel = this.getPageModel(paramMap, "queryRepaymentOrder", DbWREnums.READ);

        return pagerModel.getDataList();
    }

    @Override
    public int updateInvalidOrderStatus(Map<String, Object> parmMap) throws Exception {
        return orderDao.updateInvalidOrderStatus(parmMap);
    }

    @Override
    public OrderStatisticDto orderStatisticByUser(Long user_id) throws Exception {
        Map<String, Object> parmMap = new HashMap<String, Object>();
        parmMap.put("currentTime", FrameUtil.getTime());
        OrderStatisticDto statisticDto = orderDao.orderStatisticByUser(user_id, parmMap);
        statisticDto.setUser_id(user_id);
        return statisticDto;
    }

    @Override
    public void repaymentingOfCannel(Long order_id) throws Exception {
        if(order_id==null){
            FrameUtil.throwBaseException1("订单号不能为空");
        }
        OrderModel orderModel = this.orderDao.getModelById(order_id,true);
        if(orderModel==null){
            FrameUtil.throwBaseException1("您选择的订单不存在");
        }

        if(StagesStatusEnum.REPAYMENTING.getCode()!=orderModel.getStatus().intValue()){
            FrameUtil.throwBaseException1("当前订单状态不是还款中");
        }

        if(FundChannelEnum.YMFQ.getValue()!=orderModel.getFund_channel().intValue()){
            FrameUtil.throwBaseException1("订单资金渠道不能是第三方");
        }

        Long currtime = FrameUtil.getTime();
        //更新还款表报的状态
        Map rempayMentMap = FrameUtil.newHashMap();
        rempayMentMap.put("where_status",0);
        rempayMentMap.put("where_order_id",orderModel.getOrder_id());
        rempayMentMap.put("repayment_status",2);
        rempayMentMap.put("last_update_time",currtime);

        int count = repaymentDataService.updateByMap(rempayMentMap);
        if(count!=(orderModel.getPeriod().intValue()-orderModel.getLimit_pay().intValue())){
            FrameUtil.throwBaseException1("更新还款报表状态失败");
        }

        Map orderMap = FrameUtil.newHashMap();
        orderMap.put("order_id",orderModel.getOrder_id());
        orderMap.put("where_version",orderModel.getVersion());
        orderMap.put("status",StagesStatusEnum.MERCHANT_REFUSAL.getCode());
        orderMap.put("last_update_time",currtime);

        if(orderDao.updateByMap(orderMap,true)!=1){
            FrameUtil.throwBaseException1("更新订单表信息失败");
        }

    }

    @Resource
    private IClearDayDetailService clearDayDetailService;

    @Resource
    private ICreditLineDataService creditLineDataService;

    @Resource
    private IUserDataService userDataService;

    @Resource
    private IOrganizationService organizationService;

    @Resource
    private IProjectService projectService;

    @Resource
    private IOrderProjectDao orderProjectDao;

    @Resource
    private IRepaymentDataService repaymentDataService;

    @Resource
    private IOrderDao orderDao;

    @Resource
    private IBankService bankService;

    @Resource
    private IUserService userService;

    @Resource
    private IOrderStatusService orderStatusService;

    @Resource
    private IOrderRefuseContentService orderRefuseContentService;

    @Resource
    private IFundsService fundsService;

    @Resource
    private IFundsDataService fundsDataService;

    @Resource
    private IMerchantFundsService merchantFundsService;

    @Resource
    private IFundLoanApplyService fundLoanApplyService;

    @Resource
    private ILivingBodyAuthService livingBodyAuthService;


    @Override
    public IBaseDao getBaseDao() {
        return this.orderDao;
    }

}
